/**
 * @file strategy.cpp
 * @brief 交易策略实现
 * @details 实现了均值回归策略和趋势跟踪策略
 */

#include "strategy/strategy.h"
#include "market_data/market_data_types.h"
#include <numeric>
#include <cmath>
#include <algorithm>
#include <spdlog/spdlog.h>
#include <chrono>
#include <thread>

namespace hft {

/**
 * @brief 均值回归策略构造函�?
 * @param symbol 交易品种代码
 * @param lookback_period 回看周期
 * @param entry_threshold 入场阈�?
 * @param exit_threshold 出场阈�?
 */
MeanReversionStrategy::MeanReversionStrategy(
    const std::string& symbol,
    double lookback_period,
    double entry_threshold,
    double exit_threshold)
    : symbol_(symbol)
    , lookback_period_(lookback_period)
    , entry_threshold_(entry_threshold)
    , exit_threshold_(exit_threshold) {}

/**
 * @brief 生成交易信号
 * @param book 订单簿数�?
 * @return 交易信号
 * @details 基于价格偏离均值的程度生成交易信号
 */
Signal MeanReversionStrategy::generateSignal(const OrderBook& book) {
    // 检查是否有足够的历史数�?
    if (price_history_.size() < lookback_period_) {
        return Signal{Signal::Type::HOLD, 0.0, 0, symbol_, std::chrono::system_clock::now()};
    }

    // 计算当前价格和统计指�?
    double current_price = (book.getBestBid() + book.getBestAsk()) / 2.0;
    double mean = calculateMean();
    double std_dev = calculateStdDev();
    double z_score = (current_price - mean) / std_dev;

    // 创建信号
    Signal signal;
    signal.symbol = symbol_;
    signal.timestamp = std::chrono::system_clock::now();
    signal.price = current_price;

    // 根据z-score生成交易信号
    if (std::abs(z_score) > entry_threshold_) {
        // 价格显著偏离均值，产生交易信号
        signal.type = (z_score > 0) ? Signal::Type::SELL : Signal::Type::BUY;
        signal.quantity = 1; // 基础仓位大小
    } else if (std::abs(z_score) < exit_threshold_) {
        // 价格接近均值，平仓
        signal.type = Signal::Type::HOLD;
        signal.quantity = 0;
    } else {
        // 价格偏离程度在阈值之间，保持观望
        signal.type = Signal::Type::HOLD;
        signal.quantity = 0;
    }

    return signal;
}

/**
 * @brief 处理市场数据
 * @param msg 市场数据消息
 * @details 更新价格历史数据
 */
void MeanReversionStrategy::onMarketData(const MarketDataMessage& msg) {
    if (msg.symbol == symbol_) {
        price_history_.push_back(msg.price);
        if (price_history_.size() > lookback_period_) {
            price_history_.erase(price_history_.begin());
        }
    }
}

/**
 * @brief 处理订单簿更�?
 * @param book 订单簿数�?
 * @details 使用中间价格更新价格历史
 */
void MeanReversionStrategy::onOrderBookUpdate(const OrderBook& book) {
    // 使用中间价格更新价格历史
    double mid_price = (book.getBestBid() + book.getBestAsk()) / 2.0;
    price_history_.push_back(mid_price);
    if (price_history_.size() > lookback_period_) {
        price_history_.erase(price_history_.begin());
    }
}

/**
 * @brief 计算价格均�?
 * @return 价格均�?
 */
double MeanReversionStrategy::calculateMean() const {
    return std::accumulate(price_history_.begin(), price_history_.end(), 0.0) / price_history_.size();
}

/**
 * @brief 计算价格标准�?
 * @return 价格标准�?
 */
double MeanReversionStrategy::calculateStdDev() const {
    double mean = calculateMean();
    double sq_sum = std::accumulate(price_history_.begin(), price_history_.end(), 0.0,
        [mean](double sum, double price) {
            return sum + std::pow(price - mean, 2);
        });
    return std::sqrt(sq_sum / price_history_.size());
}

/**
 * @brief 趋势跟踪策略构造函�?
 * @param symbol 交易品种代码
 * @param short_window 短期移动平均窗口
 * @param long_window 长期移动平均窗口
 */
TrendFollowingStrategy::TrendFollowingStrategy(
    const std::string& symbol,
    int short_window,
    int long_window)
    : symbol_(symbol)
    , short_window_(short_window)
    , long_window_(long_window) {}

/**
 * @brief 生成交易信号
 * @param book 订单簿数�?
 * @return 交易信号
 * @details 基于短期和长期移动平均线的交叉生成交易信�?
 */
Signal TrendFollowingStrategy::generateSignal(const OrderBook& book) {
    // 检查是否有足够的历史数�?
    if (price_history_.size() < long_window_) {
        return Signal{Signal::Type::HOLD, 0.0, 0, symbol_, std::chrono::system_clock::now()};
    }

    // 计算移动平均�?
    double short_ma = calculateShortMA();
    double long_ma = calculateLongMA();
    double current_price = (book.getBestBid() + book.getBestAsk()) / 2.0;

    // 创建信号
    Signal signal;
    signal.symbol = symbol_;
    signal.timestamp = std::chrono::system_clock::now();
    signal.price = current_price;

    // 根据移动平均线交叉生成交易信�?
    if (short_ma > long_ma) {
        // 短期均线上穿长期均线，产生买入信�?
        signal.type = Signal::Type::BUY;
        signal.quantity = 1;
    } else if (short_ma < long_ma) {
        // 短期均线下穿长期均线，产生卖出信�?
        signal.type = Signal::Type::SELL;
        signal.quantity = 1;
    } else {
        // 均线重合，保持观�?
        signal.type = Signal::Type::HOLD;
        signal.quantity = 0;
    }

    return signal;
}

/**
 * @brief 处理市场数据
 * @param msg 市场数据消息
 * @details 更新价格历史数据
 */
void TrendFollowingStrategy::onMarketData(const MarketDataMessage& msg) {
    if (msg.symbol == symbol_) {
        price_history_.push_back(msg.price);
        if (price_history_.size() > long_window_) {
            price_history_.erase(price_history_.begin());
        }
    }
}

/**
 * @brief 处理订单簿更�?
 * @param book 订单簿数�?
 * @details 使用中间价格更新价格历史
 */
void TrendFollowingStrategy::onOrderBookUpdate(const OrderBook& book) {
    double mid_price = (book.getBestBid() + book.getBestAsk()) / 2.0;
    price_history_.push_back(mid_price);
    if (price_history_.size() > long_window_) {
        price_history_.erase(price_history_.begin());
    }
}

/**
 * @brief 计算短期移动平均�?
 * @return 短期移动平均线�?
 */
double TrendFollowingStrategy::calculateShortMA() const {
    if (price_history_.size() < short_window_) return 0.0;
    return std::accumulate(price_history_.end() - short_window_, price_history_.end(), 0.0) / short_window_;
}

/**
 * @brief 计算长期移动平均�?
 * @return 长期移动平均线�?
 */
double TrendFollowingStrategy::calculateLongMA() const {
    if (price_history_.size() < long_window_) return 0.0;
    return std::accumulate(price_history_.end() - long_window_, price_history_.end(), 0.0) / long_window_;
}

bool Strategy::init(const YAML::Node& config) {
    try {
        auto strategy_config = config["trading"]["strategy"];
        params_.name = strategy_config["name"].as<std::string>();
        params_.spread_multiplier = strategy_config["parameters"]["spread_multiplier"].as<double>();
        params_.min_spread = strategy_config["parameters"]["min_spread"].as<double>();
        params_.max_position = strategy_config["parameters"]["max_position"].as<int64_t>();
        params_.order_refresh_interval = strategy_config["parameters"]["order_refresh_interval"].as<int64_t>();
        params_.max_orders = strategy_config["parameters"]["max_orders"].as<int64_t>();
        params_.min_volume = strategy_config["parameters"]["min_volume"].as<int64_t>();
        params_.max_volume = strategy_config["parameters"]["max_volume"].as<int64_t>();
        params_.price_tick = strategy_config["parameters"]["price_tick"].as<double>();
        params_.volume_multiple = strategy_config["parameters"]["volume_multiple"].as<int64_t>();

        spdlog::info("Strategy initialized successfully");
        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to initialize strategy: {}", e.what());
        return false;
    }
}

bool Strategy::start() {
    if (running_) {
        spdlog::warn("Strategy is already running");
        return false;
    }

    running_ = true;
    strategy_thread_ = std::thread(&Strategy::run, this);
    spdlog::info("Strategy started successfully");
    return true;
}

void Strategy::stop() {
    if (!running_) {
        return;
    }

    running_ = false;
    if (strategy_thread_.joinable()) {
        strategy_thread_.join();
    }
    spdlog::info("Strategy stopped successfully");
}

void Strategy::onMarketData(const MarketDataMessage& data) {
    std::lock_guard<std::mutex> lock(mutex_);
    state_.market_data[data.symbol] = data.snapshot;
}

void Strategy::onOrderStatus(const OrderStatusType& status) {
    std::lock_guard<std::mutex> lock(mutex_);
    auto it = state_.active_orders.find(status.order_id);
    if (it != state_.active_orders.end()) {
        if (status.status == OrderStatusType::FILLED || 
            status.status == OrderStatusType::CANCELLED ||
            status.status == OrderStatusType::REJECTED) {
            state_.active_orders.erase(it);
        }
    }
}

void Strategy::onTrade(const TradeType& trade) {
    std::lock_guard<std::mutex> lock(mutex_);
    // 更新持仓
    auto it = state_.positions.find(trade.symbol);
    if (it != state_.positions.end()) {
        Position& position = it->second;
        if (trade.direction == position.direction) {
            // 开�?
            position.volume += trade.volume;
            position.open_price = (position.open_price * (position.volume - trade.volume) + 
                                 trade.price * trade.volume) / position.volume;
        } else {
            // 平仓
            position.volume -= trade.volume;
            if (position.volume == 0) {
                state_.positions.erase(it);
            }
        }
    } else if (trade.direction != OrderDirection::SELL) {
        // 新开�?
        PositionType position;
        position.symbol = trade.symbol;
        position.direction = trade.direction;
        position.volume = trade.volume;
        position.open_price = trade.price;
        state_.positions[trade.symbol] = position;
    }

    // 更新性能监控
    PerformanceMonitor::getInstance().recordTrade(trade.symbol);
}

void Strategy::onPosition(const PositionType& position) {
    std::lock_guard<std::mutex> lock(mutex_);
    state_.positions[position.symbol] = position;
    PerformanceMonitor::getInstance().updatePosition(position.symbol, position.volume);
}

void Strategy::onAccount(const Account& account) {
    std::lock_guard<std::mutex> lock(mutex_);
    state_.account = account;
}

void Strategy::run() {
    while (running_) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 遍历所有合�?
        for (const auto& market_data : state_.market_data) {
            const std::string& symbol = market_data.first;
            
            // 检查是否需要调整订�?
            if (needAdjustOrders(symbol)) {
                adjustOrders(symbol);
            }
        }

        // 等待下一次检�?
        std::this_thread::sleep_for(std::chrono::milliseconds(params_.order_refresh_interval));
    }
}

void Strategy::calculatePrices(const std::string& symbol, double& bid_price, double& ask_price) {
    const auto& snapshot = state_.market_data[symbol];
    
    // 计算中间�?
    double mid_price = (snapshot.bid_price1 + snapshot.ask_price1) / 2.0;
    
    // 计算价差
    double spread = snapshot.ask_price1 - snapshot.bid_price1;
    spread = std::max(spread * params_.spread_multiplier, params_.min_spread);
    
    // 计算买卖价格
    bid_price = mid_price - spread / 2.0;
    ask_price = mid_price + spread / 2.0;
    
    // 价格取整
    bid_price = std::floor(bid_price / params_.price_tick) * params_.price_tick;
    ask_price = std::ceil(ask_price / params_.price_tick) * params_.price_tick;
}

bool Strategy::needAdjustOrders(const std::string& symbol) {
    // 检查是否有足够的行情数�?
    if (state_.market_data.find(symbol) == state_.market_data.end()) {
        return false;
    }

    // 检查活动订单数�?
    if (state_.active_orders.size() >= params_.max_orders) {
        return false;
    }

    // 检查持仓限�?
    auto it = state_.positions.find(symbol);
    if (it != state_.positions.end() && 
        std::abs(it->second.volume) >= params_.max_position) {
        return false;
    }

    return true;
}

void Strategy::adjustOrders(const std::string& symbol) {
    // 计算买卖价格
    double bid_price, ask_price;
    calculatePrices(symbol, bid_price, ask_price);

    // 获取当前持仓
    int64_t current_position = 0;
    auto it = state_.positions.find(symbol);
    if (it != state_.positions.end()) {
        current_position = it->second.volume;
    }

    // 计算目标持仓
    int64_t target_position = 0;
    int64_t position_diff = target_position - current_position;

    // 发送订�?
    if (position_diff > 0) {
        // 需要买�?
        int64_t volume = std::min(position_diff, params_.max_volume);
        volume = std::max(volume, params_.min_volume);
        sendOrder(symbol, OrderDirection::BUY, OrderOffset::OPEN, bid_price, volume);
    } else if (position_diff < 0) {
        // 需要卖�?
        int64_t volume = std::min(-position_diff, params_.max_volume);
        volume = std::max(volume, params_.min_volume);
        sendOrder(symbol, OrderDirection::SELL, OrderOffset::OPEN, ask_price, volume);
    }
}

bool Strategy::sendOrder(const std::string& symbol, OrderDirection direction, OrderOffset offset,
                        double price, int64_t volume) {
    // 创建订单
    Order order;
    order.symbol = symbol;
    order.direction = direction;
    order.offset = offset;
    order.type = OrderType::LIMIT;
    order.price = price;
    order.volume = volume;
    order.timestamp = std::chrono::system_clock::now();

    // 风控检�?
    if (!RiskManager::getInstance().checkOrder(order)) {
        spdlog::warn("Order rejected by risk manager: {} {} {} {} {}", 
                     symbol, static_cast<int>(direction), static_cast<int>(offset), price, volume);
        return false;
    }

    // 发送订�?
    // TODO: 调用交易接口发送订�?

    // 更新活动订单
    state_.active_orders[order.order_id] = order;

    // 更新性能监控
    PerformanceMonitor::getInstance().recordOrder(symbol);

    return true;
}

bool Strategy::cancelOrder(const std::string& order_id) {
    // 检查订单是否存�?
    auto it = state_.active_orders.find(order_id);
    if (it == state_.active_orders.end()) {
        return false;
    }

    // 撤销订单
    // TODO: 调用交易接口撤销订单

    // 从活动订单中移除
    state_.active_orders.erase(it);

    return true;
}

std::shared_ptr<Strategy> StrategyFactory::createStrategy(const std::string& name) {
    auto& creators = getCreators();
    auto it = creators.find(name);
    if (it == creators.end()) {
        spdlog::error("Strategy not found: {}", name);
        return nullptr;
    }
    return it->second();
}

void StrategyFactory::registerStrategy(const std::string& name, 
                                     std::function<std::shared_ptr<Strategy>()> creator) {
    auto& creators = getCreators();
    if (creators.find(name) != creators.end()) {
        spdlog::warn("Strategy already registered: {}", name);
        return;
    }
    creators[name] = creator;
    spdlog::info("Registered strategy: {}", name);
}

std::unordered_map<std::string, std::function<std::shared_ptr<Strategy>()>>& 
StrategyFactory::getCreators() {
    static std::unordered_map<std::string, std::function<std::shared_ptr<Strategy>()>> creators;
    return creators;
}

} // namespace hft 